A ~1000-year 13C Suess Correction Model for the Study of Past Ecosystems (Redux)
code
modeling
stable isotopes
carbon emissions
Author
Jonathan Dombrosky
Published
February 11, 2023
My first published work using the R programming language was in The Holocene. In retrospect, there are some things I would change. So, let’s take the opportunity to look at some changes!
Looking back, the thing that now irks me about this model is that I didn’t show how it handled new data (data unused in model construction). In other words, I didn’t assess overfitting. Luckily, the tidymodels metapackage offers some convenient ways to assess overfitting through a simple process known as data splitting. I’ll start off by showing the original code (with only some slight modifications) from the article, and then I’ll walk you through assessing overfitting and performance on a new model. Finally, we’ll compare yearly δ13C CO2 predictions from the new and old models. The conclusion (spoiler!) is that the old model is still very robust and compares nearly perfectly to one where overfitting was explicitly evaluated (and isn’t a problem whatsoever).
Here, we randomly split the data into a training set (80% of the data) and a testing set (20% of the data). We’ll build the model using the training set and evaluate it’s performance, then we’ll use the testing set to determine how well the model predicts data unused in its construction.
loess_model_new <-loess(d13C_CO2 ~ age_AD, suess_train, span =0.10, control =loess.control(surface ="direct"))
Tidy the LOESS Object and Assess Performance Metrics
The below metrics are root mean square error (rmse), R-squared (rsq), and mean absolute error (mae). RMSE can be thought of as the standard deviation of prediction error in the model, R-squared gauges correlation, and MAE is the average amount of prediction error. We can see below that RMSE and MAE are very low, while R-squared is extremely high. The model seems highly effective at predicting yearly δ13C CO2.
# A tibble: 3 × 3
.metric .estimator .estimate
<chr> <chr> <dbl>
1 rmse standard 0.0419
2 rsq standard 0.995
3 mae standard 0.0315
The below observed (x-axis) versus predicted (y-axis) plot illustrates initial model effectviness well. The dashed line is the 1:1 line and is used to illustrate a perfect relationship between observed and predicted values.
Now we can assess how well the model handles new data. The performance metrics (rmse, rsq, and mae) indicate the model handles new data shockingly well. Again, RMSE and MAE are low and R-squared is extremely high.
test_res <-data.frame(predict(loess_model_new, newdata = suess_test, se =TRUE))test_res <-bind_cols(suess_test, test_res)suess_metric(test_res, truth = d13C_CO2, estimate = fit)
# A tibble: 3 × 3
.metric .estimator .estimate
<chr> <chr> <dbl>
1 rmse standard 0.0557
2 rsq standard 0.993
3 mae standard 0.0449